package pattern.controller;

import com.alicp.jetcache.anno.CacheInvalidate;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pattern.WorkServiceTool;
import pattern.annontations.Menu;
import pattern.annontations.Secure;
import pattern.cache.InitCache;
import pattern.cache.JetCacheUtil;
import pattern.constant.CacheKeyConstant;
import pattern.currentsession.ContextLocalCache;
import pattern.dto.SysDict;
import pattern.dto.model.system.DictAddOrUpdateModel;
import pattern.dto.model.system.DictPageModel;
import pattern.dto.response.system.DictPageResponse;
import pattern.message.MessageTool;
import pattern.model.BaseIdModel;
import pattern.result.ResponseData;
import pattern.result.ResponsePage;
import pattern.result.ResponseResultStatus;
import pattern.routing.WorkMainApiRouting;
import pattern.utils.CollectionUtil;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author Simon
 * @date 2021-04-25
 */
@Api(tags = "字典管理")
@RestController
@RequestMapping(WorkMainApiRouting.Dict.BASE)
@Menu(menuName = "sysDict", menuUri = "SysDict", foundational = false)
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Secure
@Slf4j
public class SysDictController {

    private final InitCache initCache;

    @ApiOperation(value = "获取缓存字典")
    @GetMapping(WorkMainApiRouting.Dict.GET_CACHE)
    @Menu(verify=false)
    public ResponseData<List<SysDict>> getInfo(@PathVariable String type) {
        var key = ContextLocalCache.get().getSessionLocal().concat(":").concat(type);
        var get = initCache.dicts.GET(key);
        if (get.isSuccess()) {
            return new ResponseData<>(get.getValue());
        } else {
            var sysDicts = WorkServiceTool.getSysDictService().getBaseMapper().selectList(new QueryWrapper<SysDict>().eq(SysDict.PROD_PARENT_VALUE, type));
            if (CollectionUtil.isNotEmpty(sysDicts)) {
                sysDicts.forEach(e -> e.setDictLabel(MessageTool.getDictTrans(e.getDictType(), e.getDictValue(), e.getDictLabel())));
                initCache.dicts.put(key, sysDicts);
                return new ResponseData<>(sysDicts);
            }
        }
        return new ResponseData<>(ResponseResultStatus.NON_EXISTENT);
    }

    @ApiOperation(value = "查询")
    @GetMapping(WorkMainApiRouting.Dict.LIST)
    @Secure(actionUri = "dict:search", actionName = "search", actionNote = "sysDict")
    public ResponsePage<DictPageResponse> search(DictPageModel model) {
        return WorkServiceTool.getSysDictService().pageResponse(model, DictPageResponse.class);
    }

    @ApiOperation(value = "详情")
    @GetMapping(WorkMainApiRouting.Dict.DETAIL)
    @Secure(actionUri = "dict:search")
    public ResponseData<SysDict> detail(@PathVariable Integer id) {
        return new ResponseData<>(WorkServiceTool.getSysDictService().getById(new BaseIdModel<>(id)));
    }

    @ApiOperation(value = "修改")
    @PutMapping
    @Secure(actionUri = "dict:edit", actionName = "edit", actionNote = "sysDict")
    public ResponseData<Boolean> edit(@Valid @RequestBody DictAddOrUpdateModel model) {
        if (Objects.isNull(model.getId())) {
            return new ResponseData<>(ResponseResultStatus.ILLEGAL_PARAMETER);
        }
        if (WorkServiceTool.getSysDictService().getById(model.getId()).getBuiltIn()) {
            return new ResponseData<>(ResponseResultStatus.BUILT);
        }
        model.setParentValue(null);
        model.setDictValue(model.getDictType());
        //修改子项
        WorkServiceTool.getSysDictService().updateSon(new BaseIdModel<>(model.getId()), model.getDictType());
        var flag = Objects.nonNull(WorkServiceTool.getSysDictService().saveOrUpdate(model));
        return new ResponseData<>(flag);
    }

    @ApiOperation(value = "新增")
    @PostMapping
    @Secure(actionUri = "dict:add", actionName = "add", actionNote = "sysDict")
    public ResponseData<Boolean> add(@Valid @RequestBody DictAddOrUpdateModel model) {
        if (StringUtils.isBlank(model.getParentValue())) {
            model.setParentValue(null);
            model.setDictValue(model.getDictType());
        }
        model.setBuiltIn(Boolean.FALSE);
        return new ResponseData<>(Objects.nonNull(WorkServiceTool.getSysDictService().saveOrUpdate(model)));
    }

    @ApiOperation(value = "删除")
    @DeleteMapping(WorkMainApiRouting.Dict.DELETE)
    @Secure(actionUri = "dict:remove", actionName = "delete", actionNote = "sysDict")
    public ResponseData<Boolean> delete(@PathVariable Integer[] id) {
        if (WorkServiceTool.getSysDictService().listByIds(Arrays.asList(id.clone())).stream().anyMatch(SysDict::getBuiltIn)) {
            return new ResponseData<>(ResponseResultStatus.BUILT);
        }
        return new ResponseData<>(WorkServiceTool.getSysDictService().delete(new BaseIdModel<>(id)));
    }

    @ApiOperation(value = "清理缓存")
    @DeleteMapping(WorkMainApiRouting.Dict.CLEAR_CACHE)
    @Secure(actionUri = "dict:cache", actionName = "clear_cache", actionNote = "sysDict")
    @CacheInvalidate(name = CacheKeyConstant.SysDict.DICT_KEY)
    public ResponseData<Boolean> clearCache() {
        JetCacheUtil.KeyOps.deleteKeys(CacheKeyConstant.SysDict.DICT_KEY);
        return new ResponseData<>(Boolean.TRUE);
    }

}
